package com.chat.admin.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chat.admin.domain.VO.RouteVO;
import com.chat.admin.domain.pojo.Meta;
import com.chat.admin.domain.pojo.RouteConfigsTable;
import com.chat.admin.mapper.RouteInfoMapper;
import com.chat.admin.service.IRoleService;
import com.chat.admin.service.IRouteInfoService;
import com.chat.admin.service.IRouteRoleService;
import com.chat.common.entity.Role;
import com.chat.common.entity.RouteInfo;
import com.chat.common.entity.RouteRole;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author weikjie
 * @since 2024-04-22
 */
@Service
@Slf4j
public class RouteInfoServiceImpl extends ServiceImpl<RouteInfoMapper, RouteInfo> implements IRouteInfoService {

    @Autowired
    IRoleService iRoleService;

    @Autowired
    IRouteRoleService iRouteRoleService;

    //递归
    public List<RouteVO> getRouteInfoAll1() {
        // 从数据库获取全部路由数据，简单获取没有添加条件
        List<RouteInfo> routes = list();
        // 调用递归方法构建路由树
        return buildRouteTree(routes, null).stream().map(RouteVO::new).collect(Collectors.toList());
    }

    // 递归构建路由树
    private List<RouteConfigsTable> buildRouteTree(List<RouteInfo> routes, Integer parentId) {
        List<RouteConfigsTable> routeConfigsTables = new ArrayList<>();
        // 遍历路由列表
        for (RouteInfo routeInfo : routes) {
            // 如果当前路由的父路由ID等于指定的父路由ID，则将其添加为父节点的子节点
            if (parentId == null || parentId.equals(routeInfo.getParentId())) {
                // 创建当前路由对应的 RouteConfigsTable 对象
                RouteConfigsTable routeConfigsTable = createRouteConfigsTable(routeInfo);
                // 获取当前路由的子节点列表，递归调用 buildRouteTree 方法
                List<RouteConfigsTable> children = buildRouteTree(routes, routeInfo.getId());
                routeConfigsTable.setChildren(children);
                // 将当前路由节点添加到父节点的子节点列表中
                routeConfigsTables.add(routeConfigsTable);
            }
        }
        return routeConfigsTables;
    }

    // 创建 RouteConfigsTable 对象
    private RouteConfigsTable createRouteConfigsTable(RouteInfo routeInfo) {
        RouteConfigsTable routeConfigsTable = new RouteConfigsTable();
        routeConfigsTable.setPath(routeInfo.getPath());
        routeConfigsTable.setName(routeInfo.getName());
        // 创建 Meta 对象并设置元信息
        Meta meta = new Meta();
        meta.setTitle(routeInfo.getTitle());
        meta.setIcon(routeInfo.getIcon());
        meta.setShowLink(routeInfo.getShowLink());
        meta.setShowParent(routeInfo.getShowParent());
        meta.setRank(routeInfo.getRank());
        meta.setActivePath(routeInfo.getActivePath());
        routeConfigsTable.setMeta(meta);
        return routeConfigsTable;
    }


    //Map映射
    public List<RouteVO> getRouteInfoAll2() {
        //从数据库获取全部路由数据，简单获取没有添加条件
        List<RouteInfo> routes = list();
        //获取角色列表
        List<Role> roles = iRoleService.list();
        //获取角色和路由的对应关系
        List<RouteRole> routeRoles = iRouteRoleService.list();
        //将角色表和角色和路由表转成map
        Map<Integer, List<String>> routeRolesMap = buildRouteRoleMap(roles,routeRoles);
        // 创建一个map，键值为route id, value为对应的RouteConfigsTable对象
        Map<Integer, RouteConfigsTable> routeMap = new LinkedHashMap<>();
        for (RouteInfo route : routes) {
            RouteConfigsTable node = new RouteConfigsTable();
            node.setId(route.getId());
            node.setParentId(route.getParentId());
            node.setPath(route.getPath());
            node.setName(route.getName());
            node.setComponent(route.getComponent());
            node.setRank(route.getRank());
            Meta meta = new Meta(route.getTitle(), route.getIcon(),routeRolesMap.get(route.getId()) , route.getShowLink(),route.getShowParent(), route.getRank(), route.getActivePath());
            node.setMeta(meta);
            routeMap.put(route.getId(), node);
        }
        // 创建一个列表来存放根节点
        List<RouteConfigsTable> rootRoutes = new ArrayList<>();
        // 遍历map并构建树形结构
        for (RouteConfigsTable route : routeMap.values()) {
            if (route.getParentId() == null || route.getParentId() == 0) {
                // 若parentId为空或0，说明它是根节点
                rootRoutes.add(route);
            } else {
                // 如果当前路由是子节点，把它添加到父节点的children列表中
                RouteConfigsTable parentNode = routeMap.get(route.getParentId());
                if (parentNode != null) {
                    if (parentNode.getChildren() == null) {
                        parentNode.setChildren(new ArrayList<>());
                    }
                    parentNode.getChildren().add(route);
                } else {
                    // 如果父节点不存在,打印出错误信息
                    log.info("没有找到路由 " + route.getId() + " 的父节点");
                }
            }
        }
        // 将RouteConfigTable列表转化为RouteVO列表返回
        return rootRoutes.stream().map(RouteVO::new).collect(Collectors.toList());
    }

    public Map<Integer, List<String>> buildRouteRoleMap(List<Role> roles, List<RouteRole> routeRoles) {
        // 首先，我们可以将 roles 转换为一个map，用于查找角色名
        Map<Long, String> roleMap = roles.stream()
                .collect(Collectors.toMap(Role::getId, Role::getName));

        // 将 routeRoles 转换为一个新的 map
        // 其中键是 routeId，值是与该 routeId 相关联的角色名列表
        Map<Integer, List<String>> routeRoleMap = routeRoles.stream()
                .collect(Collectors.groupingBy(
                        RouteRole::getRouteId,
                        Collectors.mapping(routeRole -> roleMap.get(routeRole.getRoleId().longValue()), Collectors.toList())
                ));

        return routeRoleMap;
    }
}
